<?php


namespace App\Service;

use RuntimeException;
use EchoPHP\Facades\Log;

class DbIndex {

    /**
     * 根据客户id计算出分库分表索引id
     * @param int $subId
     * @return array
     * @throws \Exception
     */
    public static function getDbIndex(int $subId) {
        $threshold = config('app.threshold.subid', 0);
        if ($subId > $threshold) {
            //当前客户id已经超过阈值，通知开发人员及时调整分库信息
            Log::emergency('分库索引已经超过阈值：[' . $threshold . '],当前为:[' . $subId . '],请尽快处理');
        }

        $dbIndexListPath = config('app.dbindex_list');
        if (!is_file($dbIndexListPath)) {
            throw new RuntimeException('未定义分库配置文件');
        }
        $dbIndexList = include $dbIndexListPath;

        foreach ($dbIndexList['group'] as $groupName => $groupConf) {
            if ($subId > $groupConf['startid'] && $subId <= $groupConf['endid']) {
                //命中分组，计算db序号
                $dbHash = $subId % $groupConf['tablecount'];
                foreach ($dbIndexList['dblist'][$groupName] as $dbName => $dbConf) {
                    if (in_array($dbHash, $dbConf['hashvalue'], true)) {
                        foreach ($dbIndexList['tablelist'][$dbName] as $tableName => $tableConf) {
                            if ($subId > $tableConf['startid'] && $subId <= $tableConf['endid']) {
                                return [
                                    'dbid' => $tableConf['realdbid'],
                                    'tableid' => $tableConf['realtableid'],
                                ];
                            }
                        }
                        break;
                    }
                }
                break;
            }
        }
        throw new RuntimeException('dbid计算出错');
    }

    /**
     * 获取dbindex列表
     * @return array|mixed 'dbid_1' => [1,2,3,4,5]
     * @throws \Exception
     */
    public static function getDbIndexList() {
        $dbIndexListPath = config('app.dbindex_list');
        if (!is_file($dbIndexListPath)) {
            throw new RuntimeException('未定义分库配置文件');
        }
        $dbIndexList = include $dbIndexListPath;

        $dbIdList = [];
        foreach ($dbIndexList['tablelist'] as $db => $tableItem) {
            foreach ($tableItem as $item) {
                $dbIdList['dbid_' . $item['realdbid']][] = $item['realtableid'];
            }
        }

        return $dbIdList;
    }
}